/**
 * 防抖装饰器
 *    目的: 防止抖动, 一段时间内不要抖动
 *
 *    设计思路:
 *      1. 包装原函数
 *      2. 利用定时器以及定时器可以被清理的特性
 *      3. 把包装后的函数 不断放到 Callback Queue 中, 不断清理定时器
 *      4. interval 内没有 调用, 定时器未被清理, 执行包装原函数
 *
 * */
function debounce(func, interval = 1000) {
  let timeout;

  return function () {
    // 保持原函数的 上下文与参数
    // 当前原函数是基于对象方法调用, 需要保留 this 作为方法的调用参数
    const context = this,
      args = arguments;

    // 包装原函数
    const later = function () {
      timeout = null;
      func.apply(context, args);
      console.log(`被装饰的函数执行次数`);
    };

    // 取消定时器
    clearTimeout(timeout);

    // 延时单位时间执行
    timeout = setTimeout(later, interval);

    console.log(`装饰器执行次数`);
  };
}

// 被装饰的函数
function doSomething() {
  console.log("我想干啥就干啥");
}

// 装饰后的函数
const doSomethingDebounced = debounce(doSomething, 1000);

// 连续调用
const invokeConstantly = function () {
  const length = 1000;
  let count = 1;
  while (count < length) {
    count++;
    doSomethingDebounced();
  }
};

invokeConstantly();
